package com.lifeverse.service;

import com.lifeverse.entity.KnowledgeBase;
import com.lifeverse.entity.LearningExperience;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * 学习和适应系统主服务
 * 整合经验学习、知识管理和参数调整功能
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class LearningAdaptationService {

    private final ExperienceLearningService experienceLearningService;
    private final KnowledgeManagementService knowledgeManagementService;
    private final AdaptiveParameterService adaptiveParameterService;

    /**
     * 执行完整的学习和适应流程
     */
    @Transactional
    public CompletableFuture<LearningAdaptationResult> performLearningAdaptation(Long lifeEntityId, Map<String, Object> experienceData) {
        log.info("开始为生命体 {} 执行学习和适应流程", lifeEntityId);
        
        return CompletableFuture.supplyAsync(() -> {
            try {
                LearningAdaptationResult result = new LearningAdaptationResult();
                result.setLifeEntityId(lifeEntityId);
                result.setStartTime(LocalDateTime.now());
                
                // 1. 记录学习经验
                LearningExperience experience = experienceLearningService
                        .recordLearningExperience(lifeEntityId, experienceData);
                result.setRecordedExperience(experience);
                
                // 2. 从经验中提取知识
                List<KnowledgeBase> extractedKnowledge = knowledgeManagementService
                        .extractKnowledgeFromExperience(experience);
                result.setExtractedKnowledge(extractedKnowledge);
                
                // 3. 从历史中学习
                ExperienceLearningService.LearningInsights insights = experienceLearningService
                        .learnFromHistory(lifeEntityId);
                result.setLearningInsights(insights);
                
                // 4. 调整参数
                AdaptiveParameterService.ParameterAdjustmentResult parameterResult = 
                        adaptiveParameterService.adjustLearningParameters(lifeEntityId);
                result.setParameterAdjustment(parameterResult);
                
                // 5. 维护知识库
                KnowledgeManagementService.KnowledgeMaintenanceResult maintenanceResult = 
                        knowledgeManagementService.maintainKnowledgeBase(lifeEntityId);
                result.setKnowledgeMaintenance(maintenanceResult);
                
                result.setEndTime(LocalDateTime.now());
                result.setSuccess(true);
                
                log.info("学习和适应流程完成，提取了 {} 个知识点", extractedKnowledge.size());
                return result;
                
            } catch (Exception e) {
                log.error("学习和适应流程失败", e);
                
                LearningAdaptationResult result = new LearningAdaptationResult();
                result.setLifeEntityId(lifeEntityId);
                result.setSuccess(false);
                result.setErrorMessage(e.getMessage());
                result.setEndTime(LocalDateTime.now());
                
                return result;
            }
        });
    }

    /**
     * 定时学习和适应
     */
    @Scheduled(fixedRate = 3600000) // 每小时执行一次
    @Transactional
    public void performScheduledLearningAdaptation() {
        log.info("开始定时学习和适应");
        
        try {
            // 这里可以获取所有活跃的生命体ID并执行学习适应
            // 为了演示，我们使用模拟数据
            
            // 强化重要经验
            experienceLearningService.reinforceImportantExperiences(1L);
            
            // 遗忘不重要经验
            experienceLearningService.forgetUnimportantExperiences(1L);
            
            log.info("定时学习和适应完成");
            
        } catch (Exception e) {
            log.error("定时学习和适应失败", e);
        }
    }

    /**
     * 应用学习成果到新情况
     */
    @Transactional
    public LearningApplicationResult applyLearningToSituation(Long lifeEntityId, Map<String, Object> situationData) {
        log.info("为生命体 {} 应用学习成果到新情况", lifeEntityId);
        
        try {
            LearningApplicationResult result = new LearningApplicationResult();
            result.setLifeEntityId(lifeEntityId);
            result.setApplicationTime(LocalDateTime.now());
            
            // 1. 应用经验
            ExperienceLearningService.ExperienceApplication experienceApp = 
                    experienceLearningService.applyExperienceToSituation(lifeEntityId, situationData);
            result.setExperienceApplication(experienceApp);
            
            // 2. 搜索相关知识
            String situationType = (String) situationData.get("type");
            List<KnowledgeBase> relevantKnowledge = knowledgeManagementService
                    .searchKnowledge(lifeEntityId, situationType, null);
            result.setRelevantKnowledge(relevantKnowledge);
            
            // 3. 生成综合建议
            String recommendation = generateComprehensiveRecommendation(experienceApp, relevantKnowledge);
            result.setRecommendation(recommendation);
            
            result.setSuccess(true);
            
            log.info("学习成果应用完成");
            return result;
            
        } catch (Exception e) {
            log.error("应用学习成果失败", e);
            
            LearningApplicationResult result = new LearningApplicationResult();
            result.setLifeEntityId(lifeEntityId);
            result.setSuccess(false);
            result.setErrorMessage(e.getMessage());
            result.setApplicationTime(LocalDateTime.now());
            
            return result;
        }
    }

    /**
     * 获取学习和适应统计
     */
    public LearningAdaptationStatistics getStatistics(Long lifeEntityId) {
        log.info("获取生命体 {} 的学习和适应统计", lifeEntityId);
        
        try {
            LearningAdaptationStatistics stats = new LearningAdaptationStatistics();
            stats.setLifeEntityId(lifeEntityId);
            
            // 获取知识统计
            KnowledgeManagementService.KnowledgeStatistics knowledgeStats = 
                    knowledgeManagementService.getKnowledgeStatistics(lifeEntityId);
            stats.setKnowledgeStatistics(knowledgeStats);
            
            // 获取学习洞察
            ExperienceLearningService.LearningInsights insights = 
                    experienceLearningService.learnFromHistory(lifeEntityId);
            stats.setLearningInsights(insights);
            
            return stats;
            
        } catch (Exception e) {
            log.error("获取学习和适应统计失败", e);
            return new LearningAdaptationStatistics();
        }
    }

    // 私有辅助方法
    private String generateComprehensiveRecommendation(
            ExperienceLearningService.ExperienceApplication experienceApp,
            List<KnowledgeBase> relevantKnowledge) {
        
        StringBuilder recommendation = new StringBuilder();
        
        if (experienceApp != null && experienceApp.getRecommendation() != null) {
            recommendation.append("基于经验的建议：").append(experienceApp.getRecommendation()).append("\n");
        }
        
        if (!relevantKnowledge.isEmpty()) {
            recommendation.append("相关知识：\n");
            relevantKnowledge.stream()
                    .limit(3)
                    .forEach(k -> recommendation.append("- ").append(k.getTitle()).append("\n"));
        }
        
        if (recommendation.length() == 0) {
            recommendation.append("暂无相关经验和知识，建议谨慎行动并记录结果用于学习。");
        }
        
        return recommendation.toString();
    }

    // 结果类
    public static class LearningAdaptationResult {
        private Long lifeEntityId;
        private boolean success;
        private String errorMessage;
        private LocalDateTime startTime;
        private LocalDateTime endTime;
        private LearningExperience recordedExperience;
        private List<KnowledgeBase> extractedKnowledge;
        private ExperienceLearningService.LearningInsights learningInsights;
        private AdaptiveParameterService.ParameterAdjustmentResult parameterAdjustment;
        private KnowledgeManagementService.KnowledgeMaintenanceResult knowledgeMaintenance;

        // getters and setters
        public Long getLifeEntityId() { return lifeEntityId; }
        public void setLifeEntityId(Long lifeEntityId) { this.lifeEntityId = lifeEntityId; }
        public boolean isSuccess() { return success; }
        public void setSuccess(boolean success) { this.success = success; }
        public String getErrorMessage() { return errorMessage; }
        public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; }
        public LocalDateTime getStartTime() { return startTime; }
        public void setStartTime(LocalDateTime startTime) { this.startTime = startTime; }
        public LocalDateTime getEndTime() { return endTime; }
        public void setEndTime(LocalDateTime endTime) { this.endTime = endTime; }
        public LearningExperience getRecordedExperience() { return recordedExperience; }
        public void setRecordedExperience(LearningExperience recordedExperience) { this.recordedExperience = recordedExperience; }
        public List<KnowledgeBase> getExtractedKnowledge() { return extractedKnowledge; }
        public void setExtractedKnowledge(List<KnowledgeBase> extractedKnowledge) { this.extractedKnowledge = extractedKnowledge; }
        public ExperienceLearningService.LearningInsights getLearningInsights() { return learningInsights; }
        public void setLearningInsights(ExperienceLearningService.LearningInsights learningInsights) { this.learningInsights = learningInsights; }
        public AdaptiveParameterService.ParameterAdjustmentResult getParameterAdjustment() { return parameterAdjustment; }
        public void setParameterAdjustment(AdaptiveParameterService.ParameterAdjustmentResult parameterAdjustment) { this.parameterAdjustment = parameterAdjustment; }
        public KnowledgeManagementService.KnowledgeMaintenanceResult getKnowledgeMaintenance() { return knowledgeMaintenance; }
        public void setKnowledgeMaintenance(KnowledgeManagementService.KnowledgeMaintenanceResult knowledgeMaintenance) { this.knowledgeMaintenance = knowledgeMaintenance; }
    }

    public static class LearningApplicationResult {
        private Long lifeEntityId;
        private boolean success;
        private String errorMessage;
        private LocalDateTime applicationTime;
        private ExperienceLearningService.ExperienceApplication experienceApplication;
        private List<KnowledgeBase> relevantKnowledge;
        private String recommendation;

        // getters and setters
        public Long getLifeEntityId() { return lifeEntityId; }
        public void setLifeEntityId(Long lifeEntityId) { this.lifeEntityId = lifeEntityId; }
        public boolean isSuccess() { return success; }
        public void setSuccess(boolean success) { this.success = success; }
        public String getErrorMessage() { return errorMessage; }
        public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; }
        public LocalDateTime getApplicationTime() { return applicationTime; }
        public void setApplicationTime(LocalDateTime applicationTime) { this.applicationTime = applicationTime; }
        public ExperienceLearningService.ExperienceApplication getExperienceApplication() { return experienceApplication; }
        public void setExperienceApplication(ExperienceLearningService.ExperienceApplication experienceApplication) { this.experienceApplication = experienceApplication; }
        public List<KnowledgeBase> getRelevantKnowledge() { return relevantKnowledge; }
        public void setRelevantKnowledge(List<KnowledgeBase> relevantKnowledge) { this.relevantKnowledge = relevantKnowledge; }
        public String getRecommendation() { return recommendation; }
        public void setRecommendation(String recommendation) { this.recommendation = recommendation; }
    }

    public static class LearningAdaptationStatistics {
        private Long lifeEntityId;
        private KnowledgeManagementService.KnowledgeStatistics knowledgeStatistics;
        private ExperienceLearningService.LearningInsights learningInsights;

        // getters and setters
        public Long getLifeEntityId() { return lifeEntityId; }
        public void setLifeEntityId(Long lifeEntityId) { this.lifeEntityId = lifeEntityId; }
        public KnowledgeManagementService.KnowledgeStatistics getKnowledgeStatistics() { return knowledgeStatistics; }
        public void setKnowledgeStatistics(KnowledgeManagementService.KnowledgeStatistics knowledgeStatistics) { this.knowledgeStatistics = knowledgeStatistics; }
        public ExperienceLearningService.LearningInsights getLearningInsights() { return learningInsights; }
        public void setLearningInsights(ExperienceLearningService.LearningInsights learningInsights) { this.learningInsights = learningInsights; }
    }
}